#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mg_Gesture.h"
#include "mg_Device.h"

#define INIT_SIZE (sizeof(init_Array)/2)
//上电初始化数组
//unsigned char init_Array[][2] = {	// Initial Gesture
//
//	{ 0xEF, 0x00 },
//	{ 0x41, 0xFF },//R_Int_1_En[7:0]                             
//	{ 0x42, 0x01 },//R_Int_2_En[7:0]                             
//	{ 0x46, 0x2D },//R_AELedOff_UB[7:0]                          
//	{ 0x47, 0x0F },//R_AELedOff_LB[7:0]                          
//	{ 0x48, 0x80 },//R_AE_Exposure_UB[7:0]                       
//	{ 0x49, 0x00 },//R_AE_Exposure_UB[15:8]                      
//	{ 0x4A, 0x40 },//R_AE_Exposure_LB[7:0]                       
//	{ 0x4B, 0x00 },//R_AE_Exposure_LB[15:8]                      
//	{ 0x4C, 0x20 },//R_AE_Gain_UB[7:0]                           
//	{ 0x4D, 0x00 },//R_AE_Gain_LB[7:0]                           
//	{ 0x51, 0x10 },//R_AE_EnH = 1                                
//	{ 0x5C, 0x02 },//R_SenClkPrd[5:0]                            
//	{ 0x5E, 0x10 },//R_SRAM_CLK_manual                           
//	{ 0x80, 0x42 },//GPIO setting                                
//	{ 0x81, 0x44 },//GPIO setting                                
//	{ 0x82, 0x0C },//Interrupt IO setting                        
//	{ 0x83, 0x20 },//R_LightThd[7:0]                             
//	{ 0x84, 0x30 },//R_ObjectSizeStartTh[7:0]                    
//	{ 0x85, 0x00 },//R_ObjectSizeStartTh[9:8]                    
//	{ 0x86, 0x10 },//R_ObjectSizeEndTh[7:0]                      
//	{ 0x87, 0x00 },//R_ObjectSizeEndTh[9:8]                      
//	{ 0x8B, 0x01 },//R_Cursor_ObjectSizeTh[7:0]                  
//	{ 0x8D, 0x00 },//R_TimeDelayNum[7:0]                         
//	{ 0x90, 0x06 },//R_NoMotionCountThd[6:0]                     
//	{ 0x91, 0x06 },//R_NoObjectCountThd[6:0]                     
//	{ 0x93, 0x0D },//R_XDirectionThd[4:0]                        
//	{ 0x94, 0x0A },//R_YDirectionThd[4:0]                        
//	{ 0x95, 0x0A },//R_ZDirectionThd[4:0]                        
//	{ 0x96, 0x0C },//R_ZDirectionXYThd[4:0]                      
//	{ 0x97, 0x05 },//R_ZDirectionAngleThd[3:0]                   
//	{ 0x9A, 0x14 },//R_RotateXYThd[4:0]                          
//	{ 0x9C, 0x7F },//Filter setting                              
//	{ 0x9F, 0xF9 },//R_UseBGModel is enable                      
//	{ 0xA0, 0x48 },//R_BGUpdateMaxIntensity[7:0]                 
//	{ 0xA5, 0x19 },//R_FilterAverage_Mode                        
//	{ 0xCC, 0x19 },//R_YtoZSum[5:0]                              
//	{ 0xCD, 0x0B },//R_YtoZFactor[5:0]                           
//	{ 0xCE, 0x13 },//bit[2:0] = R_PositionFilterLength[2:0]      
//	{ 0xCF, 0x62 },//bit[3:0] = R_WaveCountThd[3:0]              
//	{ 0xD0, 0x21 },//R_AbortXYRatio[4:0] & R_AbortLength[6:0]    
//	{ 0xEF, 0x01 },
//	{ 0x00, 0x1E },//Cmd_HSize[5:0]                              
//	{ 0x01, 0x1E },//Cmd_VSize[5:0]                              
//	{ 0x02, 0x0F },//Cmd_HStart[5:0]                             
//	{ 0x03, 0x0F },//Cmd_VStart[5:0]                             
//	{ 0x04, 0x02 },//Sensor skip & flip                          
//	{ 0x25, 0x01 },//R_LensShadingComp_EnH                       
//	{ 0x26, 0x00 },//R_OffsetX[6:0]                              
//	{ 0x27, 0x39 },//R_OffsetY[6:0]                              
//	{ 0x28, 0x7F },//R_LSC[6:0]                                  
//	{ 0x29, 0x08 },//R_LSFT[3:0]                                 
//	{ 0x30, 0x03 },//R_LED_SoftStart_time[7:0]                   
//	{ 0x32, 0x1A },//R_LED1_DAC_UB[4:0]                          
//	{ 0x33, 0x1A },//R_LED2_DAC_UB[4:0]                          
//	{ 0x3E, 0xFF },//Cmd_DebugPattern[7:0]                       
//	{ 0x5E, 0x3D },//analog voltage setting                      
//	{ 0x65, 0xAC },//R_IDLE_TIME[7:0] - 120fps  
//	{ 0x66, 0x00 },//R_IDLE_TIME[15:8]                           
//	{ 0x67, 0x97 },//R_IDLE_TIME_SLEEP_1[7:0]                    
//	{ 0x68, 0x01 },//R_IDLE_TIME_SLEEP_1[15:8]                   
//	{ 0x69, 0xCD },//R_IDLE_TIME_SLEEP_2[7:0]                    
//	{ 0x6A, 0x01 },//R_IDLE_TIME_SLEEP_2[15:8]                   
//	{ 0x6B, 0xB0 },//R_Obj_TIME_1[7:0]                           
//	{ 0x6C, 0x04 },//R_Obj_TIME_1[15:8]                          
//	{ 0x6D, 0x2C },//R_Obj_TIME_2[7:0]                           
//	{ 0x6E, 0x01 },//R_Obj_TIME_2[15:8]                          
//	{ 0x72, 0x01 },//R_TG_EnH                                    
//	{ 0x73, 0x35 },//Auto Sleep & Wakeup mode                    
//	{ 0x74, 0x00 },//R_Control_Mode[2:0]                         
//	{ 0x77, 0x01 },//R_SRAM_Read_EnH
//	{ 0xEF, 0x00 },
//};
const unsigned char init_Array[][2] = {
	{ 0xEF, 0x00 },
	{ 0x41, 0xFF },//R_Int_1_En[7:0]
	{ 0x42, 0x01 },//R_Int_2_En[7:0]
	{ 0x46, 0x2D },//R_AELedOff_UB[7:0]
	{ 0x47, 0x0F },//R_AELedOff_LB[7:0]
	{ 0x48, 0xE0 },//R_AE_Exposure_UB[7:0]
	{ 0x49, 0x00 },//R_AE_Exposure_UB[15:8]
	{ 0x4A, 0x70 },//R_AE_Exposure_LB[7:0]
	{ 0x4B, 0x00 },//R_AE_Exposure_LB[15:8]
	{ 0x4C, 0x20 },//R_AE_Gain_UB[7:0]
	{ 0x4D, 0x00 },//R_AE_Gain_LB[7:0]
	{ 0x51, 0x10 },//R_AE_EnH = 1
	{ 0x5C, 0x02 },//R_SenClkPrd[5:0]
	{ 0x5E, 0x10 },//R_SRAM_CLK_manual
	{ 0x80, 0x42 },//GPIO setting
	{ 0x81, 0x44 },//GPIO setting
	{ 0x82, 0x0C },//Interrupt IO setting
	{ 0x83, 0x20 },//R_LightThd[7:0]
	{ 0x84, 0x20 },//R_ObjectSizeStartTh[7:0]
	{ 0x85, 0x00 },//R_ObjectSizeStartTh[9:8]
	{ 0x86, 0x10 },//R_ObjectSizeEndTh[7:0]
	{ 0x87, 0x00 },//R_ObjectSizeEndTh[9:8]
	{ 0x8B, 0x01 },//R_Cursor_ObjectSizeTh[7:0]
	{ 0x8D, 0x00 },//R_TimeDelayNum[7:0]
	{ 0x90, 0x0C },//R_NoMotionCountThd[6:0]
	{ 0x91, 0x0C },//R_NoObjectCountThd[6:0]
	{ 0x93, 0x0D },//R_XDirectionThd[4:0]
	{ 0x94, 0x0A },//R_YDirectionThd[4:0]
	{ 0x95, 0x0A },//R_ZDirectionThd[4:0]
	{ 0x96, 0x0C },//R_ZDirectionXYThd[4:0]
	{ 0x97, 0x05 },//R_ZDirectionAngleThd[3:0]
	{ 0x9A, 0x14 },//R_RotateXYThd[4:0]
	{ 0x9C, 0x3F },//Filter setting
	{ 0x9F, 0xF9 },//R_UseBGModel is enable
	{ 0xA0, 0x48 },//R_BGUpdateMaxIntensity[7:0]
	{ 0xA5, 0x19 },//R_FilterAverage_Mode
	{ 0xAA, 0x14 },
	{ 0xAB, 0x14 },
	{ 0xCC, 0x19 },//R_YtoZSum[5:0]
	{ 0xCD, 0x0B },//R_YtoZFactor[5:0]
	{ 0xCE, 0x13 },//bit[2:0] = R_PositionFilterLength[2:0]
	{ 0xCF, 0x63 },//bit[3:0] = R_WaveCountThd[3:0]
	{ 0xD0, 0x21 },//R_AbortXYRatio[4:0] & R_AbortLength[6:0]
	{ 0xEF, 0x01 },
	{ 0x00, 0x14 },//Cmd_HSize[5:0]
	{ 0x01, 0x14 },//Cmd_VSize[5:0]
	{ 0x02, 0x14 },//Cmd_HStart[5:0]
	{ 0x03, 0x14 },//Cmd_VStart[5:0]
	{ 0x04, 0x02 },//Sensor skip & flip
	{ 0x25, 0x00 },
	{ 0x26, 0x00 },//R_OffsetX[6:0]
	{ 0x27, 0x39 },//R_OffsetY[6:0]
	{ 0x28, 0x7F },//R_LSC[6:0]
	{ 0x29, 0x08 },//R_LSFT[3:0]
	{ 0x30, 0x03 },//R_LED_SoftStart_time[7:0]
	{ 0x3E, 0xFF },//Cmd_DebugPattern[7:0]
	{ 0x4A, 0x14 },
	{ 0x4B, 0x14 },
	{ 0x4C, 0x00 },
	{ 0x4D, 0x00 },
	{ 0x5E, 0x3D },//analog voltage setting
	{ 0x65, 0xAC },//  R_IDLE_TIME[7:0]
	{ 0x66, 0x00 },//R_IDLE_TIME[15:8]
	{ 0x67, 0x97 },//R_IDLE_TIME_SLEEP_1[7:0]
	{ 0x68, 0x01 },//R_IDLE_TIME_SLEEP_1[15:8]
	{ 0x69, 0xCD },//R_IDLE_TIME_SLEEP_2[7:0]
	{ 0x6A, 0x01 },//R_IDLE_TIME_SLEEP_2[15:8]
	{ 0x6B, 0xB0 },//R_Obj_TIME_1[7:0]
	{ 0x6C, 0x04 },//R_Obj_TIME_1[15:8]
	{ 0x6D, 0x2C },//R_Obj_TIME_2[7:0]
	{ 0x6E, 0x01 },//R_Obj_TIME_2[15:8]
	{ 0x72, 0x01 },//R_TG_EnH(使能寄存器,0:Disable,1:Enable)
	{ 0x73, 0x35 },//Auto Sleep & Wakeup mode
	{ 0x74, 0x00 },//R_Control_Mode[2:0]
	{ 0x77, 0x01 },//R_SRAM_Read_EnH
	{ 0x7C, 0x90 },
	{ 0x7D, 0x01 }
};
GESTURE_STATE Gesture;
//毫秒级延时（非阻塞）
void GS_Delay_Ms(uint32_t ms)
{
	usleep(1000 * ms);
}
//手势传感器的GPIO初始化
void GS_GPIO_Init(void)
{
	//ithGpioSetMode(PAJ7620_INT_Pin, ITH_GPIO_MODE0);
	//ithGpioSetIn(PAJ7620_INT_Pin);
	//ithGpioEnable(PAJ7620_INT_Pin);
}
//PAJ7620U2写一个字节数据
uint8_t GS_Write_Reg(uint8_t REG_Address, uint8_t REG_data)
{
	I2C2_Write_Reg(PAJ7620_ID, REG_Address, &REG_data,1);
}
//PAJ7620U2读一个字节数据
uint8_t GS_Read_Byte(uint8_t REG_Address)
{
	return I2C2_Read_Reg(PAJ7620_ID, REG_Address);
}
//PAJ7620唤醒
void GS_WakeUp(void)
{
	GS_Write_Reg(PAJ_REGITER_BANK_SEL, PAJ_BANK0);
}
//选择PAJ7620U2 BANK区域
void paj7620u2_selectBank(bank_e bank)
{
	switch (bank)
	{
		case BANK0: GS_Write_Reg(PAJ_REGITER_BANK_SEL, PAJ_BANK0); break;//BANK0寄存器区域
		case BANK1: GS_Write_Reg(PAJ_REGITER_BANK_SEL, PAJ_BANK1); break;//BANK1寄存器区域
	}
}
//PAJ7620U2唤醒
uint8_t paj7620u2_wakeup(void)
{
	uint16_t data;
	GS_WakeUp();//唤醒PAJ7620U2
	GS_Delay_Ms(10);//唤醒时间>400us

	paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
	data = GS_Read_Byte(0x01);//读取状态
	data <<= 8;
	data += GS_Read_Byte(0x00);//读取状态
	if (data != 0x7620) return 0; //唤醒失败
	return 1;
}
//PAJ7620U2初始化
//返回值：0:失败 1:成功
uint8_t PAJ7620_Init(void)
{
	uint8_t i, count;
	uint8_t status;
	count = 5;
	while (count != 0)
	{
		count--;
		status = paj7620u2_wakeup();//唤醒PAJ7620U2
		if (status)
		{
			printf("Moorgen INFO:Found Gesture sensor PAJ7620U2\n");
			for (i = 0; i<INIT_SIZE; i++)
			{
				GS_Write_Reg(init_Array[i][0], init_Array[i][1]);//初始化PAJ7620U2
			}
			ithGpioSetIn(PAJ7620_INT_Pin);
			ithGpioSetMode(PAJ7620_INT_Pin, ITH_GPIO_MODE0);
			
			printf("Moorgen INFO:Gesture sensor PAJ7620U2 init succeed!\n");
			return 1;
		}
		else
		{
			GS_Delay_Ms(10);
		}
	}
	printf("Moorgen INFO:Do not Found Gesture sensor PAJ7620U2\n");
	return 0;
}

void Gesture_Check(void)
{
	uint16_t status,ObjectSize;
	int ret;
	CmdType temp_Action = Null_Action;

	paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域
	
	status = GS_Read_Byte(PAJ_GET_INT_FLAG2);//手势感应参数（挥动）
	status <<= 8;
	status += GS_Read_Byte(PAJ_GET_INT_FLAG1);//手势感应参数(上下左右前后顺逆)
	if (status && (Sys_Config.byte.Gesture_En == 0x02) && (Sys_Config.byte.Panal_EN == 0x01) && Gesture.Gesture_En)
	{
		printf("Moorgen INFO:Gesture sensor detect gestures  ");
		////检测到的面积大小
		//ObjectSize = GS_Read_Byte(0xB2) & 0x0F;
		//ObjectSize <<= 8;
		//ObjectSize += GS_Read_Byte(0xB1);
		//printf("Moorgen INFO:Gesture sensor ObjectSize %d\n", ObjectSize);

		switch (status)
		{
		case GES_UP:			//向上
			if ((Sys_Config.byte.Gesture_Config & 0x04))
			{
				temp_Action = Up_Slide;
				printf("UP!\n");
				ScreenSaverRefresh();//退出屏保
			}
			break;
		case GES_DOWM:			//向下
			if ((Sys_Config.byte.Gesture_Config & 0x08))
			{
				temp_Action = Down_Slide;
				printf("DOWM!\n");
				ScreenSaverRefresh();//退出屏保
			}
			break;
		case GES_LEFT:			//向左
			if ((Sys_Config.byte.Gesture_Config & 0x01))
			{
				temp_Action = Right_Slide;
				printf("LEFT!\n");
				ScreenSaverRefresh();//退出屏保
			}
			break;
		case GES_RIGHT:			//向右
			if ((Sys_Config.byte.Gesture_Config & 0x02))
			{
				temp_Action = Left_Slide;
				printf("RIGHT!\n");
				ScreenSaverRefresh();//退出屏保
			}
			break;
		case GES_FORWARD:		//向前
			//temp_Action = Forward;
			printf("FORWARD!\n");
			//ScreenSaverRefresh();//退出屏保
			break;
		case GES_BACKWARD:		//向后
			//temp_Action = Backward;
			printf("BACKWARD!\n");
			//ScreenSaverRefresh();//退出屏保
			break;
		case GES_CLOCKWISE:		//顺时针
			//temp_Action = Clockwise_Rotation;
			printf("CLOCKWISE!\n");
			//ScreenSaverRefresh();//退出屏保
			break;
		case GES_COUNT_CLOCKWISE://逆时针
			//temp_Action = Anticlockwise_Rotation;
			printf("COUNT_CLOCKWISE!\n");
			//ScreenSaverRefresh();//退出屏保
			break;
		case GES_WAVE:			//挥动
			//temp_Action = Wave;
			printf("WAVE!\n");
			//ScreenSaverRefresh();//退出屏保
			break;
		default:
			break;
		}
		//赋值手势结果
		if (temp_Action != Null_Action)
		{
			if (Action_Cmd.User_Action == temp_Action)
			{
				Action_Cmd.Action_Times++;
			}
			else
			{
				Action_Cmd.User_Action = temp_Action;
				Action_Cmd.Action_Times = 1;
			}
		}
	}
}

//手势定时复位
void Gesture_Timer_Reset(void)
{
	Gesture.Gesture_En = false;
	Gesture.Gesture_Timer = 0;
}
//手势定时开启使能
void Gesture_Timer_Poll(void)
{
	if (Gesture.Gesture_Timer<=1000)
		Gesture.Gesture_Timer++;
	else
	{
		Gesture.Gesture_En = true;
	}
}